#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     rc
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/12/13
-------------------------------------------------
   修改描述-2021/12/13:
   PS：代码主要参考值flask框架
-------------------------------------------------
"""
from grpcframe.utils.cache_property import rlock_cached_property
from google.protobuf import json_format
from pydantic import ValidationError
from grpcframe.exception import BadRequestException
from grpcframe.validation import raw_errors_info
from typing import Dict, Tuple
import grpc

class Request:

    def __init__(self, request, context: grpc.ServicerContext):
        """ 初始化Request实例
        :param request: 原始请求
        :param context: 请求上下文
        """
        self.request = request
        self.context = context

    @rlock_cached_property
    def rpc_event(self):
        """ 返回RPC事件
        """

        if self.context is not None:
            # 反射查询
            return getattr(self.context, "_rpc_event")
        return None

    @rlock_cached_property
    def headers(self):
        """ 获取请求头
        """
        if self.rpc_event is not None:
            # 反射查询
            metadata = getattr(self.rpc_event, "invocation_metadata")
            return dict(metadata)
        return None

    @rlock_cached_property
    def method(self):
        """ 获取本次请求调用的方法
        """
        if self.call_details is not None:
            # 反射查询
            method = getattr(self.call_details, "method")
            return method.decode("utf8") if method else method
        return None

    @rlock_cached_property
    def service(self):
        """ 获取本次请求的Service
        """
        if self.method is not None:
            return self.method.split("/")[-2]
        return None

    @rlock_cached_property
    def call_details(self):
        """ 返回调用详情
        """
        if self.rpc_event is not None:
            # 反射查询
            return getattr(self.rpc_event, "call_details")
        return None

    @rlock_cached_property
    def parse_metadata_peer(self) -> Dict:
        '''
        获取请求头信息
        :param context:
        :return:
        '''
        metadata = {}
        for key, value in self.context.invocation_metadata():
            metadata[key.strip()] = value.strip()
        # 返回信息
        metadata.update({'peer': self.context.peer()})
        return metadata

    @rlock_cached_property
    def parse_request_action(self) -> Dict:
        '''
        获取当前RPC的请求参数信息，进行字典的序列化
        :param request:
        :return:
        '''
        request_dict = json_format.MessageToDict(self.request, preserving_proto_field_name=True)
        return request_dict

    @rlock_cached_property
    def parse_request(self) -> Dict:
        '''
        获取当前RPC的请求参数信息，进行字典的序列化
        :param request:
        :return:
        '''
        request_dict = json_format.MessageToDict(self.request, preserving_proto_field_name=True)
        return request_dict

    @rlock_cached_property
    def validation_request(self, model: type):
        request_model = None
        try:
            # 模型实例化
            request_model = model(**self.parse_request())
            pass
        except ValidationError as exc:
            raise BadRequestException(message=raw_errors_info(exc))
        finally:
            return request_model

    @rlock_cached_property
    def parse_request_metadata(self) -> Tuple:
        '''
        解析请求参数和请求头信息并返回
        :param request:
        :param context:
        :return:
        '''
        return self.parse_request, self.parse_metadata_peer
